"""
CUDA和CuPy兼容性验证模块
功能: 验证系统中CUDA和CuPy的安装状态、版本兼容性和GPU设备信息
用途: 用于诊断GPU加速环境是否正确配置,确保排班算法能够使用GPU加速
返回: 打印GPU环境信息和测试结果,无返回值
"""
# 导入日志模块，用于记录程序运行状态和错误信息
import logging
# 导入系统模块，用于获取Python解释器版本信息
import sys


# 定义函数：验证CUDA和CuPy的兼容性
def verify_cuda_cupy_compatibility():
    """
    验证CUDA和CuPy的兼容性
    功能: 检查CUDA环境和CuPy库的安装状态、版本信息和兼容性
    流程: 
    1. 尝试导入CuPy库
    2. 检查CUDA是否可用
    3. 获取并显示GPU设备信息
    4. 执行简单的GPU计算测试
    异常处理: 捕获并显示导入错误和其他异常
    """
    try:
        # 尝试导入cupy库，这是一个与NumPy兼容的GPU加速计算库
        import cupy as cp

        # 打印验证开始的标题，使用等号分隔以增强可读性
        print("\n=== CUDA 和 CuPy 版本验证 ===")
        # 打印当前Python版本，包括主版本、次版本和修订版本
        print(f"Python版本: {sys.version}")
        # 打印当前CuPy版本，用于检查与CUDA版本的兼容性
        print(f"CuPy版本: {cp.__version__}")

        # 检查CUDA是否可用，如果不可用将执行else分支
        if cp.cuda.is_available():
            # 获取CUDA运行时版本号，这是一个整数值
            runtime_version = cp.cuda.runtime.runtimeGetVersion()
            # 格式化CUDA版本号为主版本.次版本格式，例如11.7
            cuda_version = f"{runtime_version // 1000}.{(runtime_version % 1000) // 10}"
            # 打印CUDA版本，用于确认与CuPy版本的兼容性
            print(f"CUDA版本: {cuda_version}")

            # 获取系统中可用的GPU设备数量，用于多GPU系统
            device_count = cp.cuda.runtime.getDeviceCount()
            # 打印发现的GPU设备数量，使用等号分隔以增强可读性
            print(f"\n=== 发现 {device_count} 个GPU设备 ===")

            # 遍历每个GPU设备，获取并显示详细信息
            for device_id in range(device_count):
                # 获取当前GPU设备的属性，包括名称、计算能力和内存大小等
                device = cp.cuda.runtime.getDeviceProperties(device_id)
                # 打印GPU设备编号，从0开始计数
                print(f"\nGPU {device_id}:")
                # 打印GPU设备名称，如"GeForce RTX 3080"，需要解码字节字符串
                print(f"  设备名称: {device['name'].decode()}")
                # 打印GPU计算能力版本，格式为"主版本.次版本"，如"8.6"
                print(f"  计算能力: {device['major']}.{device['minor']}")
                # 打印GPU总内存大小，将字节转换为GB并保留两位小数
                print(f"  总内存: {device['totalGlobalMem'] / (1024 ** 3):.2f} GB")

            # 打印GPU功能测试标题，表示开始执行实际计算测试
            print("\n=== 执行GPU功能测试 ===")
            try:
                # 创建测试用的cupy数组，用于验证基本GPU计算功能
                x = cp.array([1, 2, 3])
                # 尝试进行简单的GPU计算（开平方），验证计算正确性
                y = cp.sqrt(x)
                # 测试成功提示，表示GPU可以正常执行计算任务
                print("GPU计算测试: 成功")
            except Exception as e:
                # 测试失败时打印错误信息，帮助诊断GPU计算问题
                print(f"GPU计算测试失败: {str(e)}")

        else:
            # CUDA不可用时打印警告信息，表示无法使用GPU加速
            print("警告: CUDA不可用")
            print("请检查:")
            # 列出可能的原因1：NVIDIA驱动未安装或版本不兼容
            print("1. NVIDIA驱动是否正确安装")
            # 列出可能的原因2：CUDA工具包未安装或路径配置错误
            print("2. CUDA工具包是否正确安装")
            # 列出可能的原因3：CuPy库与CUDA版本不匹配
            print("3. CuPy是否正确安装")

    except ImportError:
        # CuPy库导入失败时打印错误信息，表示缺少必要的库
        print("错误: 未安装CuPy")
        # 提供安装命令建议，帮助用户安装正确版本的CuPy
        print("请运行: pip install cupy-cuda[xx]x")
        # 说明版本号替换方式，如cupy-cuda11x对应CUDA 11.x
        print("其中[xx]替换为您的CUDA版本")

    except Exception as e:
        # 捕获并处理其他未预期的错误，提供通用错误信息
        print(f"验证过程出错: {str(e)}")


# 当文件作为主程序运行时执行验证函数，而作为模块导入时不执行
if __name__ == "__main__":
    verify_cuda_cupy_compatibility()